package cn.njyd.corejava.thread.myday03;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

class Account{
    private String id;
    private int balance;
    private boolean flag = true;
    private Lock lock = new ReentrantLock();

    private Condition con_withdraw = lock.newCondition();

    private Condition con_deposit = lock.newCondition();

    public void deposit(int money){
        lock.lock();
        try{
            while(!flag) {
                //
                con_deposit.await();
            }
//            System.out.println(Thread.currentThread().getName()+"对客户"+this.id+"存款");
            this.balance+=money;
            System.out.println(Thread.currentThread().getName()+"存款，余额为"+this.balance);
            this.flag = !this.flag;
            con_withdraw.signalAll();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally{
            lock.unlock();
        }
    }

    public void withdraw(int money) {
        lock.lock();
        try{
            if (this.balance-money<0) {
                System.out.println("余额不足");
                return ;
            }
            while(this.flag) {
                con_withdraw.await();
            }

            this.balance-=money;
            System.out.println(Thread.currentThread().getName()+"对帐户取款"+money+"，余额为"+this.balance);
            this.flag = !this.flag;
            con_deposit.signalAll();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public int getBalance() {
        return balance;
    }

    public void setBalance(int balance) {
        this.balance = balance;
    }

    public boolean isFlag() {
        return flag;
    }

    public void setFlag(boolean flag) {
        this.flag = flag;
    }

    public Lock getLock() {
        return lock;
    }

    public void setLock(Lock lock) {
        this.lock = lock;
    }

    public Condition getCon_withdraw() {
        return con_withdraw;
    }

    public void setCon_withdraw(Condition con_withdraw) {
        this.con_withdraw = con_withdraw;
    }

    public Condition getCon_deposit() {
        return con_deposit;
    }

    public void setCon_deposit(Condition con_deposit) {
        this.con_deposit = con_deposit;
    }
}

public class ThreadAwaitSignalDemo01 {
    public static void main(String[] args) {
        Account account = new Account();
        account.setId("666");
        account.setBalance(500);
        Thread t1 = new Thread(() -> {
            for (int i = 1; i <= 20; i++) {
                account.withdraw(100);
            }
        }, "用户A");
        Thread t2 = new Thread(() -> {
            for (int i=1;i<=10;i++) {
                account.deposit(100);
            }
        },"用户B");
        Thread t3 = new Thread(() -> {
            for (int i=1;i<=10;i++) {
                account.deposit(100);
            }
        },"用户C");
        t1.start();
        t2.start();
        t3.start();
    }
}